package cn.happy.favdish.view.activities

import android.Manifest
import android.app.Activity
import android.app.Dialog
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.provider.MediaStore
import android.provider.Settings
import android.util.Log
import android.view.Menu
import android.view.View
import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.appcompat.app.AlertDialog
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.toBitmap
import androidx.recyclerview.widget.LinearLayoutManager
import cn.happy.favdish.R
import cn.happy.favdish.application.FavDishApplication
import cn.happy.favdish.databinding.ActivityAddUpdateDishBinding
import cn.happy.favdish.databinding.DialogCustomImageSelectionBinding
import cn.happy.favdish.databinding.DialogCustomListBinding
import cn.happy.favdish.model.entities.FavDish
import cn.happy.favdish.utils.Constants
import cn.happy.favdish.view.adapter.CustomListItemAdapter
import cn.happy.favdish.view.viewmodel.FavDishViewModel
import cn.happy.favdish.view.viewmodel.FavDishViewModelFactory
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.OutputStream
import java.util.UUID

class AddUpdateDishActivity : AppCompatActivity(), View.OnClickListener {
    private lateinit var mBinding: ActivityAddUpdateDishBinding
    private var mImagePath:String = ""

    private val mFavDishViewModel : FavDishViewModel by viewModels{
        FavDishViewModelFactory((application as FavDishApplication).repository)
    }

    private var mFavDishDetails: FavDish? = null

    // 权限
    private lateinit var requestPermissionLauncher:ActivityResultLauncher<Array<String>>
    // 启动相机
    private val activityCameraRestLauncher = registerForActivityResult(
        ActivityResultContracts.TakePicturePreview()){ result ->

                    Glide.with(this)
                        .load(result)
                        .centerCrop()
                        .diskCacheStrategy(DiskCacheStrategy.ALL)
                        .listener(object : RequestListener<Drawable>{
                            override fun onLoadFailed(
                                e: GlideException?,
                                model: Any?,
                                target: Target<Drawable>,
                                isFirstResource: Boolean
                            ): Boolean {
                                return false
                            }

                            override fun onResourceReady(
                                resource: Drawable,
                                model: Any,
                                target: Target<Drawable>?,
                                dataSource: DataSource,
                                isFirstResource: Boolean
                            ): Boolean {
                                mImagePath = saveImageToInternalStorage(resource.toBitmap())
                                return false
                            }

                        })
                        .into(mBinding.ivDishImage)
                    mBinding.ivAddDishImage.setImageDrawable(ContextCompat.getDrawable(this,
                        R.drawable.ic_vector_edit))

    }

    // 启动图库
    private val activityGalleryRestLauncher = registerForActivityResult(
        ActivityResultContracts.StartActivityForResult()){ result ->
        when (result.resultCode){
            Activity.RESULT_OK -> {
               result.data?.data.let {
//                   mBinding.ivDishImage.setImageURI(it)
                   Glide.with(this)
                       .load(it)
                       .centerCrop()
                       .diskCacheStrategy(DiskCacheStrategy.ALL)
                       .listener(object : RequestListener<Drawable>{
                           override fun onLoadFailed(
                               e: GlideException?,
                               model: Any?,
                               target: Target<Drawable>,
                               isFirstResource: Boolean
                           ): Boolean {
                               return false
                           }

                           override fun onResourceReady(
                               resource: Drawable,
                               model: Any,
                               target: Target<Drawable>?,
                               dataSource: DataSource,
                               isFirstResource: Boolean
                           ): Boolean {
                               mImagePath = saveImageToInternalStorage(resource.toBitmap())
                               return false
                           }

                       })
                       .into(mBinding.ivDishImage)

                   mBinding.ivAddDishImage.setImageDrawable(ContextCompat.getDrawable(this,
                       R.drawable.ic_vector_edit))
               }
            }
            else -> {
                Toast.makeText(this,"你未选择任何照片",Toast.LENGTH_SHORT).show()
            }
        }
    }


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mBinding = ActivityAddUpdateDishBinding.inflate(layoutInflater)
        setContentView(mBinding.root)

        if(intent.hasExtra(Constants.EXTRA_DISH_DETAILS)){
            mFavDishDetails = intent.getParcelableExtra(Constants.EXTRA_DISH_DETAILS)

            mFavDishDetails?.let {
                if(it.favDishId != 0){
                    Glide.with(this)
                        .load(it.image)
                        .centerCrop()
                        .into(mBinding.ivDishImage)

                    mBinding.etAddTitle.setText(it.title)
                    mBinding.etAddType.setText(it.type)
                    mBinding.etAddCategory.setText(it.category)
                    mBinding.etAddIngredients.setText(it.ingredients)
                    mBinding.etAddCookTime.setText(it.cookingTime)
                    mBinding.etAddCookDirection.setText(it.directionToCook)
                }
            }
        }

        setupActionBar()


        mBinding.ivAddDishImage.setOnClickListener(this)
        mBinding.etAddType.setOnClickListener(this)
        mBinding.etAddCategory.setOnClickListener(this)
        mBinding.etAddCookTime.setOnClickListener(this)
        mBinding.btnAddDish.setOnClickListener(this)


        // 处理权限请求结果
        requestPermissionLauncher = registerForActivityResult(
            ActivityResultContracts.RequestMultiplePermissions()){ permissions ->
            val deniedPermissions : MutableList<String> = ArrayList()
            var deniedMsg = ""

            for(p in REQUIRED_PERMISSIONS){
                if(permissions[p] == false){
                    // 没有获得授权
                    deniedPermissions.add(p)
                    if(p.contains("CAMERA")){
                        deniedMsg += " 相机"
                    }

                    if(p.contains("STORAGE")){
                        deniedMsg += " 存储"
                    }
                }
            }

            if(deniedPermissions.isNotEmpty()){
                showRationalDialogForPermission(deniedMsg)
            }
        }

        // 请求权限
        requestPermission()


    }

    /**
     * Toolbar
     */
    private fun setupActionBar(){
        setSupportActionBar(mBinding.toolbarAddDish)
        if(mFavDishDetails != null && mFavDishDetails!!.favDishId != 0){
            supportActionBar?.let{
                it.title = resources.getString(R.string.title_edit_dish)
            }
        }else{
            supportActionBar?.let{
                it.title = resources.getString(R.string.title_add_dish)
            }
        }

        supportActionBar?.setDisplayHomeAsUpEnabled(true)
        mBinding.toolbarAddDish.setNavigationOnClickListener{
            onBackPressed()
        }
    }

    /**
     * 点击事件
     */
    override fun onClick(v: View?) {
        if (v != null) {
            when(v.id){
                R.id.iv_add_dish_image -> {
                    customImageSelectionDialog()
                    return
                }
                R.id.et_add_type -> {
                    customItemsDialog(resources.getString(R.string.title_select_dish_type),Constants.dishTypes(),Constants.DISH_TYPE)
                    return
                }
                R.id.et_add_category -> {
                    customItemsDialog(resources.getString(R.string.title_select_dish_category),Constants.dishCategories(),Constants.DISH_CATEGORY)
                    return
                }
                R.id.et_add_cook_time -> {
                    customItemsDialog(resources.getString(R.string.title_select_dish_cook_time),Constants.dishCookingTimes(),Constants.DISH_COOKING_TIME)
                    return
                }
                R.id.btn_add_dish -> {

                    val title = mBinding.etAddTitle.text.toString().trim{ it <= ' '}
                    val type = mBinding.etAddTitle.text.toString().trim{ it <= ' '}
                    val category = mBinding.etAddCategory.text.toString().trim{ it <= ' '}
                    val ingredients = mBinding.etAddIngredients.text.toString().trim{ it <= ' '}
                    val cookingTime = mBinding.etAddCookTime.text.toString().trim{ it <= ' '}
                    val cookDirection = mBinding.etAddCookDirection.text.toString().trim{ it <= ' '}

                    var dishId = 0
                    var imageSource = Constants.DISH_IMAGE_SOURCE_LOCAL
                    var favoriteDish = false

                    mFavDishDetails?.let{
                        // 编辑
                        if(it.favDishId != 0){
                            dishId = it.favDishId
                            imageSource = it.imageSource
                            favoriteDish = it.favoriteDish
                        }
                    }

                    val favDish = FavDish(mImagePath,Constants.DISH_IMAGE_SOURCE_LOCAL,title,
                        type,category,ingredients,cookingTime,cookDirection,favoriteDish,dishId)

                    if(dishId == 0){
                        mFavDishViewModel.insert(favDish)
                        Toast.makeText(this,"新增成功",Toast.LENGTH_SHORT).show()
                    }else{
                        mFavDishViewModel.update(favDish)
                        Toast.makeText(this,"修改成功",Toast.LENGTH_SHORT).show()
                    }


                    finish()

                }
            }
        }
    }

    /**
     * 选择照片对话框
     */
    private fun customImageSelectionDialog(){
        val dialog = Dialog(this)
        val binding: DialogCustomImageSelectionBinding =
            DialogCustomImageSelectionBinding.inflate(layoutInflater)
        dialog.setContentView(binding.root)
        dialog.setCancelable(true)
        binding.tvCamera.setOnClickListener{
            // 点击相机
            dialog.dismiss()

            if(allPermissionGranted()){
                //启动相机
                activityCameraRestLauncher.launch(null)
            }else{
                requestPermission()
            }
        }
        binding.tvGallery.setOnClickListener{
            // 点击图库
            dialog.dismiss()

            if(allPermissionGranted()){
                // 打开图库
                val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
                activityGalleryRestLauncher.launch(intent)
            }else{
                requestPermission()
            }

        }

        dialog.show()

    }

    private fun requestPermission(){
        val deniedPermissions : MutableList<String> = ArrayList()
        for (permission in REQUIRED_PERMISSIONS){
            val isGranted = ActivityCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED

            if(!isGranted){
                deniedPermissions.add(permission)
            }
        }
        requestPermissionLauncher.launch(deniedPermissions.toTypedArray())
    }

    private fun allPermissionGranted() = REQUIRED_PERMISSIONS.all {
        ContextCompat.checkSelfPermission(baseContext,
            it) == PackageManager.PERMISSION_GRANTED
    }

    /**
     * 权限拒绝对话框
     */
    private fun showRationalDialogForPermission(deniedMsg:String){
        AlertDialog.Builder(this).setMessage("你拒绝权限:$deniedMsg")
            .setPositiveButton("去授权"){
                _,_ -> try {
                    val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                    val uri = Uri.fromParts("package",packageName,null)
                    intent.data = uri
                    startActivity(intent)
                }catch (e:ActivityNotFoundException){
                    e.printStackTrace()
                }
            }
            .setNegativeButton("取消"){
               dialog,_ -> dialog.dismiss()
            }.show()
    }


    private fun saveImageToInternalStorage(bitmap: Bitmap):String{
        val wrapper = ContextWrapper(applicationContext)

        var file = wrapper.getDir(IMAGES_DIRECTORY,Context.MODE_PRIVATE)
        file = File(file,"${UUID.randomUUID()}.jpg")
        try{
            val stream : OutputStream = FileOutputStream(file)
            bitmap.compress(Bitmap.CompressFormat.JPEG,80,stream)
            stream.flush()
            stream.close()
        }catch (e:IOException){
            e.printStackTrace()
        }

        return  file.absolutePath
    }

    /**
     * 列表选择对话框
     */
    private fun customItemsDialog(title:String,itemsList:List<String>,selection:String){
        val customListDialog = Dialog(this)
        val binding : DialogCustomListBinding = DialogCustomListBinding.inflate(layoutInflater)

        customListDialog.setContentView(binding.root)

        binding.dialogListTvTitle.text = title

        binding.dialogRvList.layoutManager = LinearLayoutManager(this)

        val adapter = CustomListItemAdapter(this,null,itemsList,selection)
        binding.dialogRvList.adapter = adapter

        customListDialog.show()
    }

    fun selectedListItem(item:String, selection: String){
        when(selection){
            Constants.DISH_TYPE -> {
                mBinding.etAddType.setText(item)
                return
            }
            Constants.DISH_CATEGORY -> {
                mBinding.etAddCategory.setText(item)
                return
            }
            Constants.DISH_COOKING_TIME -> {
                mBinding.etAddCookTime.setText(item)
                return
            }

        }
    }


    companion object{
        private val REQUIRED_PERMISSIONS = mutableListOf(
            Manifest.permission.CAMERA
        ).apply {
            if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.P){
                add(Manifest.permission.WRITE_EXTERNAL_STORAGE)
            }
            if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2){
                add(Manifest.permission.READ_EXTERNAL_STORAGE)
            }
        }.toTypedArray()

        private const val IMAGES_DIRECTORY = "FavDishImages"
    }
}